package com.ubs.lingua.buildtool.cs.parameters;

import java.io.Serializable;

/**
 * The Lingua C# Build Agent C# command line compiler parameters.
 */
public class CscParameters implements Serializable {

    private static final long serialVersionUID = -6293908360372653365L;

    private Configuration assemblyConfig = Configuration.RELEASE;

    private boolean multyConfig = false;

    private Platform assemblyPlatform = Platform.ANYCPU;

    private boolean multyPlatform = false;

    private boolean generateXmlDoc = false;

    private boolean unsafe = false;

    /**
     * Predefined debug-centric configurations of the C# command line compiler.
     */
    public static enum Configuration {
        /**
         * Instructs C# command line compiler to emit a *.pdb file for use by debugging tools, such as cordbg.exe, dbgclr.exe, or Visual Studio. 
         */
        DEBUG,
        /**
         * Instruct the C# command line compiler to generate the smallest and fastest assembly as possible.
         * This configurations emits metadata that also instructs the CLR to optimize code at run time.
         */
        RELEASE;
    }

    /**
     * Predefined target CPU configurations of the C# command line compiler that must be present to host the assembly.
     * By and large, this option is only useful if your C# code base is making use of P/Invoke and/or unsafe code constructs.
     */
    public static enum Platform {
        /**
         * x64
         */
        X64,
        /**
         * x86
         */
        X86,
        /**
         * Any CPU
         */
        ANYCPU;
    }

    /**
     * Returns the debug-centric configuration of the C# command line compiler.
     * The value set at class initialization time is {@link Configuration#RELEASE}.
     * @return the debug-centric configuration of the C# command line compiler
     */
    public Configuration getAssemblyConfiguration() {
        return assemblyConfig;
    }

    /**
     * <p>Sets the debug-centric configuration of the C# command line compiler that will be returned by {@link #getAssemblyConfiguration()}.</p>
     * <p>The value set at class initialization time is {@link Configuration#RELEASE}.</p>
     * @param assemblyConfig the debug-centric configuration of the C# command line compiler to be associated with this build batch
     */
    public void setAssemblyConfiguration(final Configuration assemblyConfig) {
        this.assemblyConfig = assemblyConfig;
    }

    /**
     * <p>Returns the target CPU configuration of the C# command line compiler.</p>
     * <p>The value set at class initialization time is {@link Platform#ANYCPU}.</p>
     * <p><b>Note:</b> By and large, setting this option to any value other than {@link Platform#ANYCPU} only useful if your C# code base
     * is making use of P/Invoke and/or unsafe code constructs.</p>
     * @return the target CPU configuration of the C# command line compiler
     */
    public Platform getAssemblyPlatform() {
        return assemblyPlatform;
    }

    /**
     * <p>Sets the target CPU configurations of the C# command line compiler that will be returned by {@link #getAssemblyPlatform()}.</p>
     * <p>The value set at class initialization time is {@link Platform#ANYCPU}.</p>
     * <p><b>Note:</b> By and large, setting this option to any value other than {@link Platform#ANYCPU} only useful if your C# code base
     * is making use of P/Invoke and/or unsafe code constructs.</p>
     * @param assemblyPlatform the target CPU configurations of the C# command line compiler to be associated with this build batch
     */
    public void setAssemblyPlatform(final Platform assemblyPlatform) {
        this.assemblyPlatform = assemblyPlatform;
    }

    /**
     * <p>Returns true if XML documentation files will be generated.</p>
     * <p>The value set at class initialization time is <code>false</code>.</p>
     * @return true if XML documentation files will be generated
     */
    public boolean isGenerateXmlDoc() {
        return generateXmlDoc;
    }

    /**
     * <p>Switch XML documentation files generation on/off.</p>
     * <p>The value set at class initialization time is <code>false</code>.</p>
     * @param generateXmlDoc whether XML documentation files should be generated
     */
    public void setGenerateXmlDoc(final boolean generateXmlDoc) {
        this.generateXmlDoc = generateXmlDoc;
    }

    /**
     * <p>Returns true if it is allowed to declare an unsafe scope in a C# files, which are typically used to manipulate C++ style pointers.</p>
     * <p>The value set at class initialization time is <code>false</code>.</p>
     * @return true if it is allowed to declare an unsafe scope in a C# files
     */
    public boolean isUnsafe() {
        return unsafe;
    }

    /**
     * <p>Allows/disallows declaring an unsafe scope in a C# files.
     * When enabled, this option allows your C# files to declare an unsafe scope, which are typically used to manipulate C++ style pointers.</p>
     * <p>The value set at class initialization time is <code>false</code>.</p>
     * @param unsafe whether unsafe scope in a C# files is allowed
     */
    public void setUnsafe(final boolean unsafe) {
        this.unsafe = unsafe;
    }

    /**
     * <p>Returns true if the Lingua C# Build Agent will compile the assembly for multiple configurations.
     * Several assembly DLLs will be compiled for each supported configuration ({@link Configuration#RELEASE}
     * and {@link Configuration#DEBUG}).</p>
     * <p>The value set at class initialization time is <code>false</code>.</p>
     * @return true if compiling the assembly for multiple configuration is enabled
     */
    public boolean isMultyConfig() {
        return multyConfig;
    }

    /**
     * <p>Enables/disables compiling the assembly for multiple configurations.
     * When enabled, several assembly DLLs will be compiled by the the Lingua C# Build Agent
     * for each supported configuration ({@link Configuration#RELEASE} and {@link Configuration#DEBUG}).</p>
     * <p>The value set at class initialization time is <code>false</code>.</p>
     * @param multyConfig whether compiling the assembly for multiple configuration is enabled or disabled
     */
    public void setMultyConfig(final boolean multyConfig) {
        this.multyConfig = multyConfig;
    }

    /**
     * <p>Returns true if the Lingua C# Build Agent will compile the assembly for multiple platforms.
     * Several assembly DLLs will be compiled for each supported platform ({@link Platform#X64},
     * {@link Platform#X86} and {@link Platform#ANYCPU}).</p>
     * <p>The value set at class initialization time is <code>false</code>.</p>
     * @return true if compiling the assembly for multiple platforms is enabled
     */
    public boolean isMultyPlatform() {
        return multyPlatform;
    }

    /**
     * <p>Enables/disables compiling the assembly for multiple platforms.
     * When enabled, several assembly DLLs will be compiled by the the Lingua C# Build Agent
     * for each supported platform ({@link Platform#X64}, {@link Platform#X86} and
     * {@link Platform#ANYCPU}).</p>
     * <p>The value set at class initialization time is <code>false</code>.</p>
     * @param multyPlatform whether compiling the assembly for multiple platform is enabled or disabled
     */
    public void setMultyPlatform(final boolean multyPlatform) {
        this.multyPlatform = multyPlatform;
    }

}
